package com.iretailer.report.analyze.device.face.horizon;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import com.iretailer.report.analyze.commonUtil.CommonUtil;
import com.iretailer.report.analyze.device.face.horizon.model.Alarm;
import com.iretailer.report.analyze.device.face.horizon.model.Face;
import com.iretailer.report.analyze.device.face.horizon.model.Feature;
import com.iretailer.report.analyze.device.face.horizon.model.HorizonModel;
import com.iretailer.report.model.Categories;
import com.iretailer.report.model.FaceAlarmDevice;
import com.iretailer.report.model.FaceAlarmRecord;
import com.iretailer.report.service.CategoriesService;
import com.iretailer.report.service.FaceAlarmRecordService;
import com.iretailer.report.service.FaceAlarmService;
import com.iretailer.report.util.GetId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: xjw
 * @Date: 2019/11/4 0004 16:18
 * @Description:
 */
@Component
public class FacePush {
    private static final Logger log = LoggerFactory.getLogger(FacePush.class);

    @Autowired
    private FaceAlarmService faceAlarmService;

    private static CategoriesService categoriesService;

    private static FaceAlarmRecordService faceAlarmRecordService;

    @Autowired
    public void setCategoriesService(CategoriesService categoriesService) {
        this.categoriesService = categoriesService;
    }

    @Autowired
    public void setFaceAlarmRecordService(FaceAlarmRecordService faceAlarmRecordService) {
        this.faceAlarmRecordService = faceAlarmRecordService;
    }

    // key 为 deviceId_LocalDateTime
    private static final Cache<String, FaceMapInnerClass> cache = CacheBuilder.newBuilder()
            .expireAfterWrite(10, TimeUnit.SECONDS)
//            .expireAfterAccess(10, TimeUnit.SECONDS)
            .removalListener(new RemovalListener<String, FaceMapInnerClass>() {
                @Override
                public void onRemoval(RemovalNotification<String, FaceMapInnerClass> remove) {
                    if (remove.wasEvicted()) {
                        FaceMapInnerClass faceMapInnerClass = remove.getValue();
                        if (!faceMapInnerClass.featureStatus) {
                            Map<String, Categories> ageTypeMap = categoriesService.getAgeTypeMap();
                            Face face = faceMapInnerClass.face;
                            FaceAlarmRecord faceAlarmRecord = toFaceAlarmRecord(faceMapInnerClass.did, face.getAge(), face.getGender(), face.getDateTime(), face.getSnapShot(), face.getPersonId(), ageTypeMap);
                            pushAndSave(faceAlarmRecord);
                        }
                    }
                }
            })
            .build();

    private class FaceMapInnerClass {
        Long did;
        LocalDateTime localDateTime;
        Face face;
        boolean featureStatus;

        public FaceMapInnerClass(LocalDateTime localDateTime, Face face, boolean featureStatus) {
            this.localDateTime = localDateTime;
            this.face = face;
            this.featureStatus = featureStatus;
        }
    }


    public void faceAlarm(HorizonModel horizonModel) {
        String deviceId = horizonModel.getProperties().getDeviceId();
        if (horizonModel.getSmartData() != null && horizonModel.getSmartData().getAlarm() != null) {
            List<FaceAlarmDevice> faceAlarmDevices = faceAlarmService.getFaceAlarmDeviceByDeviceId(deviceId);
            Alarm alarm = horizonModel.getSmartData().getAlarm();
            if (faceAlarmDevices.size() > 0) {
                FaceAlarmDevice fas = faceAlarmDevices.get(0);
                // 在推送时间内
                if (CommonUtil.judgeBusinessTime(alarm.getDateTime(), fas.getStartTime(), fas.getEndTime())) {
                    Map<String, Categories> ageTypeMap = categoriesService.getAgeTypeMap();
                    FaceAlarmRecord face = toFaceAlarmRecord(fas.getDid(), alarm.getAge(), alarm.getGender(), alarm.getDateTime(), alarm.getSnapShot(), alarm.getPersonId(), ageTypeMap);
                    pushAndSave(face);
                    log.error("---- alarm deviceId:{} personId: {}", deviceId, alarm.getPersonId());
                } else {
                    log.error("---- alarm deviceId：{} ", deviceId);
                }
            } else {
                log.error("---- alarm No alarm time associated   deviceId:{}",deviceId);
            }
        }else {
            log.error("--- deviceId {}  alarm face is null  ",deviceId);
        }
    }

    public void addPushMap(HorizonModel horizonModel) {
        LocalDateTime dataTime = null;
        Face face = null;
        String personId = null;
        boolean featureStatus = false;
        if (horizonModel.getSmartData().getFace() != null) {
            face = horizonModel.getSmartData().getFace();
            dataTime = face.getDateTime();
            personId = face.getPersonId();
        }
        if (horizonModel.getSmartData().getFeature() != null) {
            Feature feature = horizonModel.getSmartData().getFeature();
            if (feature.getDatabaseId().equals("alarm")) {
                personId = feature.getPersonId();
                dataTime = feature.getDateTime();
                featureStatus = true;
            }
        }
        if (personId != null) {
            String deviceId = horizonModel.getProperties().getDeviceId();
            List<FaceAlarmDevice> faceAlarmDevices = faceAlarmService.getFaceAlarmDeviceByDeviceId(deviceId);
            if (faceAlarmDevices.size() > 0) {
                FaceAlarmDevice fas = faceAlarmDevices.get(0);
                // 在推送时间内
                if (CommonUtil.judgeBusinessTime(dataTime, fas.getStartTime(), fas.getEndTime())) {

                    FaceMapInnerClass faceMapInnerClass = cache.getIfPresent(personId);
                    if (faceMapInnerClass == null) {
                        faceMapInnerClass = new FaceMapInnerClass(dataTime, face, featureStatus);
                    }
                    faceMapInnerClass.did = fas.getDid();
                    if (featureStatus) {
                        faceMapInnerClass.featureStatus = featureStatus;
                    }
                    if (face != null) {
                        faceMapInnerClass = faceMapInnerClass;
                    }
                    cache.put(personId, faceMapInnerClass);
                }
            }
        }
    }


    public static void pushAndSave(FaceAlarmRecord face) {
        // 推送 to do list
        faceAlarmRecordService.saveRecordAndImage(face);
    }


    private static FaceAlarmRecord toFaceAlarmRecord(Long did, int age, int gender, LocalDateTime dateTime, String snapShot, String personId, Map<String, Categories> ageTypeMap) {
        Categories ageType = ageTypeMap.get(String.valueOf(age));
        FaceAlarmRecord faceAlarmRecord = new FaceAlarmRecord();
        if (ageType != null) {
            faceAlarmRecord.setAgeType(ageType.getData());
        } else {
            faceAlarmRecord.setAgeType("");
        }

        faceAlarmRecord.setGender(gender);
        faceAlarmRecord.setDate(dateTime.toLocalDate());
        faceAlarmRecord.setDateTime(dateTime);
        faceAlarmRecord.setDid(did);
//        genderAge.setImage(String.format("%s%s", "data:image/png;base64,", face.getSnapShot()));
        faceAlarmRecord.setImage(snapShot);
        faceAlarmRecord.setPersonId(personId);
        String imageKey = did + "-" + GetId.LID();
        faceAlarmRecord.setImageKey(imageKey);
        faceAlarmRecord.setImageUrl(String.format("/report/%s/getFaceImage.action", imageKey));
        faceAlarmRecord.setStatus(-1);
        return faceAlarmRecord;
    }
}
